{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Preparação de Dados\n",
    "\n",
    "\n",
    "Muitos algoritmos de aprendizagem de máquinas fazem suposições sobre seus dados. Muitas vezes, é uma boa idéia preparar seus dados de forma a melhor expor a estrutura do problema aos algoritmos de aprendizagem de máquina que você pretende usar. Neste capítulo, você descobrirá como preparar seus dados para a aprendizagem de máquinas em Python usando scikit-learn. Depois de completar esta lição você saberá como:\n",
    "\n",
    "1. Reduzir os dados;\n",
    "2. Padronizar dados; \n",
    "3. Normalize os dados; \n",
    "4. Binarizar dados.\n",
    "\n",
    "Necessidade de pré-processamento de dados\n",
    "\n",
    "Pré-processar seus dados é um passo necessário. Uma dificuldade é que diferentes algoritmos fazem diferentes pressupostos sobre seus dados e podem exigir transformações diferentes. Além disso, quando você segue todas as regras e prepara seus dados, às vezes os algoritmos podem oferecer melhores resultados sem pré-processamento.\n",
    "\n",
    "Geralmente, eu recomendaria a criação de muitas visualizações e transformações diferentes dos seus dados, e depois exercitaria um punhado de algoritmos em cada visualização do seu conjunto de dados. Isso irá ajudá-lo a eliminar as transformações de dados que podem ser melhores ao expor a estrutura do seu problema em geral.\n",
    "\n",
    "## Transformações de dados\n",
    "\n",
    "Nesta lição, você trabalhará através de 4 diferentes tarefas de pré-processamento de dados para aprendizagem em máquina. O conjunto de dados do diabetes indiano Pima é usado em cada exemplo. Cada exemplo segue a mesma estrutura:\n",
    "  \n",
    "1. Carregue o conjunto de dados a partir de um URL.\n",
    "2. Divida o conjunto de dados nas variáveis de entrada e saída para o aprendizado da máquina. \n",
    "3. Aplique uma transformação de pré-processamento nas variáveis de entrada.\n",
    "4. Resuma os dados para mostrar a mudança.\n",
    "\n",
    "A biblioteca scikit-learn fornece dois idiomas padrão para transformar dados. Cada um é útil em diferentes circunstâncias. As transformações são calculadas de tal forma que elas podem ser aplicadas aos dados de treinamento e a qualquer amostra de dados que você possa ter no futuro. A documentação scikit-learn contém algumas informações sobre como usar vários métodos de pré-processamento diferentes:\n",
    "\n",
    "1. Fit e Multiple Transform.\n",
    "2. Combinado Fit-And-Transform.\n",
    "  \n",
    "  \n",
    "O método Fit e Multiple Transform é a abordagem preferida. Você chama a função fit () para preparar os parâmetros da transformação uma vez em seus dados. Depois, você pode usar a função transform () nos mesmos dados para prepará-lo para modelagem e novamente no conjunto de dados de teste ou validação ou novos dados que você possa ver no futuro. O Combined Fit-And-Transform é uma conveniência que você pode usar para uma tarefa fora. Isso pode ser útil se você estiver interessado em traçar ou resumir os dados transformados. Você pode revisar a API de pré-processamento no scikit-learn clicando neste [link](http://scikit-learn.org/stable/modules/classes.html#module-sklearn.preprocessing).\n",
    "\n",
    "## Alterar a Escala dos Dados\n",
    "\n",
    "Quando seus dados são compostos por atributos com diferentes escalas, muitos algoritmos de aprendizado de máquina podem se beneficiar de redimensionar os atributos para que todos tenham a mesma escala. Muitas vezes, isso é referido como normalização e os atributos são freqüentemente redimensionados para o intervalo entre 0 e 1. Isso é útil para algoritmos de otimização usados no núcleo de algoritmos de aprendizado de máquinas como gradiente descendente. Também é útil para algoritmos que ponderam as entradas de regressão e redes neurais ou algoritmos que utilizam medidas de distância como k-Nearest Neighbours. Você pode redimensionar seus dados usando scikit-learn usando a classe [MinMaxScaler](http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.353  0.744  0.59   0.354  0.     0.501  0.234  0.483]\n",
      " [ 0.059  0.427  0.541  0.293  0.     0.396  0.117  0.167]\n",
      " [ 0.471  0.92   0.525  0.     0.     0.347  0.254  0.183]\n",
      " [ 0.059  0.447  0.541  0.232  0.111  0.419  0.038  0.   ]\n",
      " [ 0.     0.688  0.328  0.354  0.199  0.642  0.944  0.2  ]]\n"
     ]
    }
   ],
   "source": [
    "# Rescalando dados (entre 0 e 1)\n",
    "from pandas import read_csv\n",
    "from numpy import set_printoptions\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "filename = 'pima-indians-diabetes.data'\n",
    "names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] \n",
    "dataframe = read_csv(filename, names=names)\n",
    "array = dataframe.values\n",
    "# separar array em entrada e saída\n",
    "X = array[:,0:8]\n",
    "Y = array[:,8]\n",
    "scaler = MinMaxScaler(feature_range=(0, 1))\n",
    "rescaledX = scaler.fit_transform(X)\n",
    "# sumarizando os dados transformados\n",
    "set_printoptions(precision=3)\n",
    "print(rescaledX[0:5,:])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Padronizar dados\n",
    "\n",
    "A padronização é uma técnica útil para transformar atributos assumindo que os mesmos seguem  uma distribuição gaussiana, modificando as médias e desvios padrão para uma distribuição gaussiana padrão com uma média de 0 e um desvio padrão de 1. É mais adequado para técnicas que assumem uma distribuição gaussiana nas variáveis de entrada e funcionam melhor com dados redimensionados, como regressão linear, regressão logística e análise de discriminação linear. Você pode padronizar dados usando scikit-learn com a classe [StandardScaler](http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler. html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.64   0.848  0.15   0.907 -0.693  0.204  0.468  1.426]\n",
      " [-0.845 -1.123 -0.161  0.531 -0.693 -0.684 -0.365 -0.191]\n",
      " [ 1.234  1.944 -0.264 -1.288 -0.693 -1.103  0.604 -0.106]\n",
      " [-0.845 -0.998 -0.161  0.155  0.123 -0.494 -0.921 -1.042]\n",
      " [-1.142  0.504 -1.505  0.907  0.766  1.41   5.485 -0.02 ]]\n"
     ]
    }
   ],
   "source": [
    "# Standardize data (0 mean, 1 stdev)\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from pandas import read_csv\n",
    "from numpy import set_printoptions\n",
    "filename = 'pima-indians-diabetes.data'\n",
    "names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] \n",
    "dataframe = read_csv(filename, names=names)\n",
    "array = dataframe.values\n",
    "# separate array into input and output components\n",
    "X = array[:,0:8]\n",
    "Y = array[:,8]\n",
    "scaler = StandardScaler().fit(X)\n",
    "rescaledX = scaler.transform(X)\n",
    "# summarize transformed data\n",
    "set_printoptions(precision=3)\n",
    "print(rescaledX[0:5,:])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Normalizar Dados\n",
    "\n",
    "A normalização em scikit-learn refere-se a reescalonamento de cada observação (linha) para ter um comprimento de 1 (chamado de norma de unidade ou vetor com o comprimento de 1 em álgebra linear). Este método de pré-processamento pode ser útil para conjuntos de dados esparsos (quantidade grande de zeros) com atributos de escalas variáveis quando aplicados aos algoritmos que ponderam valores de entrada, como redes neurais e algoritmos que usam medidas de distância, como k-Nearest Neighbours. Você pode normalizar dados em Python com scikit-learn usando a classe [Normalizer](http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.Normalizer.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 0.034  0.828  0.403  0.196  0.     0.188  0.004  0.28 ]\n",
      " [ 0.008  0.716  0.556  0.244  0.     0.224  0.003  0.261]\n",
      " [ 0.04   0.924  0.323  0.     0.     0.118  0.003  0.162]\n",
      " [ 0.007  0.588  0.436  0.152  0.622  0.186  0.001  0.139]\n",
      " [ 0.     0.596  0.174  0.152  0.731  0.188  0.01   0.144]]\n"
     ]
    }
   ],
   "source": [
    "# Normalize data (length of 1)\n",
    "from sklearn.preprocessing import Normalizer\n",
    "from pandas import read_csv\n",
    "from numpy import set_printoptions\n",
    "filename = 'pima-indians-diabetes.data'\n",
    "names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] \n",
    "dataframe = read_csv(filename, names=names)\n",
    "array = dataframe.values\n",
    "# separate array into input and output components\n",
    "X = array[:,0:8]\n",
    "Y = array[:,8]\n",
    "scaler = Normalizer().fit(X)\n",
    "normalizedX = scaler.transform(X)\n",
    "# summarize transformed data\n",
    "set_printoptions(precision=3)\n",
    "print(normalizedX[0:5,:])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## Binarizar dados \n",
    "\n",
    "Você pode transformar seus dados usando um limite binário. Todos os valores acima do limite são marcados como 1 e todos iguais ou inferiores são marcados como 0. Isso é chamado de binarizar seus dados ou limitar seus dados. Pode ser útil quando você tem probabilidades de que você deseja criar valores nítidos. Também é útil quando você está realizando a engenharia de características e quer adicionar novas características (features) que possuem algum significativo. Você pode criar novos atributos binários no Python usando scikit-learn com a classe [Binarizer](http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.Binarizer.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.  1.  1.  1.  0.  1.  1.  1.]\n",
      " [ 1.  1.  1.  1.  0.  1.  1.  1.]\n",
      " [ 1.  1.  1.  0.  0.  1.  1.  1.]\n",
      " [ 1.  1.  1.  1.  1.  1.  1.  1.]\n",
      " [ 0.  1.  1.  1.  1.  1.  1.  1.]]\n"
     ]
    }
   ],
   "source": [
    "# binarization\n",
    "from sklearn.preprocessing import Binarizer\n",
    "from pandas import read_csv\n",
    "from numpy import set_printoptions\n",
    "filename = 'pima-indians-diabetes.data'\n",
    "names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] \n",
    "dataframe = read_csv(filename, names=names)\n",
    "array = dataframe.values\n",
    "# separate array into input and output components\n",
    "X = array[:,0:8]\n",
    "Y = array[:,8]\n",
    "binarizer = Binarizer(threshold=0.0).fit(X)\n",
    "binaryX = binarizer.transform(X)\n",
    "# summarize transformed data\n",
    "set_printoptions(precision=3)\n",
    "print(binaryX[0:5,:])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
